from configs.logging_config import configure_logging
from loguru import logger
from server.chat.knowledge_base_chat_ import knowledge_base_chat
from server.chat.utils import generate_unique_id, log_content
from fastapi import Body, Request
from fastapi.responses import StreamingResponse
from server.utils import BaseResponse
from configs.kb_config import VECTOR_SEARCH_TOP_K, SCORE_THRESHOLD
from configs.model_config import HISTORY_LEN, LLM_MODELS, TEMPERATURE, MAX_TOKENS
from sse_starlette.sse import EventSourceResponse
from server.utils import create_chat_response_event
from server.db.repository.message_repository import get_message_by_user_id
from server.chat.utils import llm_chat
from configs.other_config import INSTRUCTIONS

configure_logging()


# 定义一个方法,参数包含uid,
async def otherpc_knowledgebase_chat(
        uid: str = Body(..., description="用户ID"),
        query: str = Body(..., description="用户输入", examples=["你好"]),
        knowledge_base_name: str = Body(..., description="知识库名称", examples=["samples"]),
        stream: bool = Body(False, description="流式输出"),
        prompt_name: str = Body(
            ...,
            description="使用的prompt模板名称(在configs/prompt_config.py中配置)"
        ),
        request: Request = None
):
    try:
        # 检查knowledge_base_name和prompt_name是否配套
        if knowledge_base_name.lower() != prompt_name.split("_")[1].lower():
            logger.error(f"The knowledge base name and the prompt name do not correspond.")
            return BaseResponse(code=40003,
                                msg="The knowledge base name and the prompt name do not correspond. Please verify that both the knowledge base and the prompt names are entered accurately.")
        if knowledge_base_name not in ["MaKeBoLuo"]:
            from instruction.GuoTai.GuoTai import intent_recognition
            if knowledge_base_name == "XiaoKa":
                from instruction.XiaoKaPC.XiaoKaPC import intent_recognition
            if knowledge_base_name == "GuoTai":
                from instruction.GuoTai.GuoTai import intent_recognition
            try:
                instruction = await intent_recognition(query)
            except Exception as e:
                logger.error(f"Failed to RE recognize intent: {e}")
                instruction = "-1"

            if instruction in INSTRUCTIONS:
                request_id = "I_" + generate_unique_id()
                answer = None
                try:
                    log_content(uid=uid, query=query, answer=answer, instruction=instruction, unique_id=request_id)
                    return EventSourceResponse(create_chat_response_event(response_text=answer, instruction=instruction,
                                                                    unique_id=request_id, finish=True, data_content=""))
                except Exception as e:
                    logger.error(f"Failed to create chat response stream: {e}")
                    return BaseResponse(code=50005, msg="Failed to create chat response stream.")

            # 检查是否识别到了意图
            try:
                instruction = await llm_chat(query, f"{knowledge_base_name}_Intention_Recognition", 0.1)
            except Exception as e:
                logger.error(f"Failed to LLM recognize intent: {e}")
                instruction = "-1"
        else:
            instruction = "-1"
        request_id = generate_unique_id()
        # 检查是否识别到了意图
        if instruction in INSTRUCTIONS:
            request_id = "I_" + request_id
            answer = None  # 没有需要返回给用户的回复

            try:
                log_content(uid=uid, query=query, answer=answer, instruction=instruction, unique_id=request_id)
                return EventSourceResponse(create_chat_response_event(response_text=answer, instruction=instruction,
                                                                unique_id=request_id, finish=True, data_content=""))
            except Exception as e:
                logger.error(f"Failed to create chat response stream: {e}")
                return BaseResponse(code=50005, msg="Failed to create chat response stream.")
        else:
            request_id = "D_" + request_id
            histories = get_message_by_user_id(user_id=uid, history_len=HISTORY_LEN)
            # 知识库对话的返回值
            try:
                response = await knowledge_base_chat(uid=uid,
                                                     query=query,
                                                     request_id=request_id,
                                                     history=histories,
                                                     knowledge_base_name=knowledge_base_name,
                                                     stream=stream,
                                                     prompt_name=prompt_name,
                                                     top_k=VECTOR_SEARCH_TOP_K,
                                                     score_threshold=SCORE_THRESHOLD,
                                                     model_name=LLM_MODELS[0],
                                                     temperature=TEMPERATURE,
                                                     max_tokens=MAX_TOKENS,
                                                     request=request)
            except Exception as e:
                logger.error(f"Failed to perform knowledge base chat: {e}")
                return BaseResponse(code=50006, msg="Failed to perform knowledge base chat.")
            try:
                if stream:
                    event_source_response = EventSourceResponse(response)
                    return event_source_response
                else:
                    streaming_response = StreamingResponse(response)
                    return streaming_response
            except Exception as e:
                logger.error(f"Failed to create streaming response: {e}")
                return BaseResponse(code=50007, msg="Failed to create streaming response.")
    except Exception as e:
        # 捕获其他所有未被捕获的异常
        logger.error(f"Unexpected error occurred: {e}")
        return BaseResponse(code=50008, msg="An unexpected error occurred.")

